# based on https://www.hanshq.net/command-line-android.html

PKGDIR	:= org/libsdl/app
SRCDIR	:= ./src
BLDDIR	:= ./build
RSCDIR	:= ./res
OBJDIR	:= $(BLDDIR)/obj
RSCSRC	:= $(SRCDIR)/$(PKGDIR)/R.java
SOURCES	:= $(shell find -wholename "$(SRCDIR)/*.java") $(RSCSRC)
OBJECTS	:= $(SOURCES:$(SRCDIR)/%.java=$(OBJDIR)/%.class)
JNILIB	=  ./libs
JNILIBS	:= $(shell find -wholename "$(JNILIB)/*.so")
APKDIR	:= $(BLDDIR)/apk
APKLIB	:= $(APKDIR)/lib
APKLIBS	:= $(JNILIBS:$(JNILIB)/%=$(APKLIB)/%)
DLVKBC	:= $(APKDIR)/classes.dex
UNALIGN	:= $(BLDDIR)/unaligned.apk
UNSIGN	:= $(BLDDIR)/unsigned.apk
KEYFILE	:= ./keystore.jks
TARGET	:= $(BLDDIR)/main.apk

# We will use shell variables to more conveniently refer to the SDK we installed before.
SDK = $(HOME)/dev/android_sdk
BUILD_TOOLS = $(SDK)/build-tools/28.0.2
PLATFORM = $(SDK)/platforms/android-28
AAPT = $(BUILD_TOOLS)/aapt
DX = $(BUILD_TOOLS)/dx
ZIPALGN = $(BUILD_TOOLS)/zipalign
APKSIGN = $(BUILD_TOOLS)/apksigner

apk: $(TARGET)

$(RSCSRC) : $(RSCDIR) AndroidManifest.xml
	# The firs)t build step is to generate the R.java file, which is used for referring to resources (such as R.id.my_text above). This is done using the Android Asset Packaging Tool, aapt:
	$(AAPT) package -f -m -J $(SRCDIR) -S $(RSCDIR) \
      -M AndroidManifest.xml -I "$(PLATFORM)/android.jar"
	# which creates R.java.
	# The -f flag causes aapt to overwrite any existing output file, -m causes it to create package directories under the output directory, and -J makes it generate the R.java file and sets the output directory. -S points out the resource directory, -M specifies the manifest, and -I adds the platform .jar as an "include file".

$(OBJECTS): $(SOURCES) | $(OBJDIR)
	# Now that all the Java code is ready, we can compile it using javac:
	javac -source 1.7 -target 1.7 -bootclasspath "$(JAVA_HOME)/jre/lib/rt.jar" \
      -classpath "$(PLATFORM)/android.jar" -d $(OBJDIR) \
      $(SOURCES)
	# (The 1.7 and -bootclasspath ure used to emit Java 7 byte code, which the Android tools expect, despite using JDK version 8.)

$(DLVKBC) : $(OBJECTS) | $(OBJDIR) $(APKDIR)
	# The Java compiler created .class files containing byte code for the Java Virtual Machine. That then has to be translated to Dalvik byte code using the dx tool:
	$(DX) --dex --output=$(DLVKBC) $(OBJDIR)

$(UNALIGN): $(APKLIBS) $(DLVKBC) AndroidManifest.xml | $(APKDIR)
	# We then package the contents of the build/apk/ directory together with the manifest and resources into an Android Application Package (APK) file, again using the aapt tool:
	$(AAPT) package -f -M AndroidManifest.xml -S res/ \
		  -I "$(PLATFORM)/android.jar" \
		  -F $(UNALIGN) $(APKDIR)
	# The application has now been built, but the APK file needs to be signed before any device will allow running it, even in debug mode, and zipaligned if we ever want to publish it in the Play Store.

$(UNSIGN): $(UNALIGN)
	# First, we run the zipalign tool, which aligns uncompressed files in the APK on 4-byte boundaries for easier memory mapping:
	$(ZIPALGN) -f -p 4 \
		  $(UNALIGN) $(UNSIGN)

$(KEYFILE):
	# Then we use the Java keytool to create a key store and key for signing:
	keytool -genkeypair -keystore $(KEYFILE) -alias androidkey \
		  -validity 10000 -keyalg RSA -keysize 2048 \
		  -storepass android -keypass android

$(TARGET): $(if $(wildcard $(KEYFILE)),,$(KEYFILE)) $(UNSIGN) | $(OBJDIR) $(APKDIR) $(APKLIB)
	# and use that key to sign our application with apksigner:
	$(APKSIGN) sign --ks $(KEYFILE) \
		  --ks-key-alias androidkey --ks-pass pass:android \
		  --key-pass pass:android --out $(TARGET) \
		  $(UNSIGN)
	# Et voilà, we have successfully built an Android application.

# All build artifacts will be put in subdirectories of the build directory which we create here.
$(OBJDIR):
	mkdir -p $(OBJDIR)
$(APKDIR):
	mkdir -p $(APKDIR)
$(APKLIB):
	mkdir -p $(APKLIB)

ndk:
	ndk-build

$(APKLIB)/%.so: $(JNILIB)/%.so
	@mkdir -p $(@D)
	cp $< $@

clean:
	ndk-build clean distclean
	# lot of dangerous rm -rf cleaning
	rm -f $(RSCSRC)
	rm -rf $(BLDDIR)
	rm -rf $(JNILIB)
	rm -rf obj # where does this come from??

.PHONY : ndk $(KEYFILE) claen
